/*
    Dominate 3D - A cube-based game of life

    Copyright (C) 2007, Craig H. Miller (kidmosey@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CELL_H__
#define __CELL_H__

#include <vector>
#include <list>
#include <set>
#include <map>

#include "vector.h"
#include "color.h"

class Player;

class Cell
{
public:
    typedef enum
    {
        NOT_HIGHLIGHTED = 0,
        SELECTED,
        JUMP_TO,
        COPY_TO
    } ESTATE;
    typedef std::list<std::pair<Cell *, ESTATE> > HighlightList;

    Cell(const CVector3D &v1, const CVector3D &v2, const CVector3D &v3, const CVector3D &v4);

    ~Cell();

    CVector3D GetNormal() const;

    void Render() const;

    void DrawBorder(const Color &c) const;

    int GetState() const;
    void SetState(const ESTATE state) { m_state = state; }

    int GetID() const { return m_id; }

    void InitSurroundingCells();
    const std::set<Cell *> &GetSurroundingCells() const;

    int TakeOver(Player *p);

    bool CanMove();

    HighlightList &Select();
    void Unselect();

    bool IsEmpty() const;

    void RenderHighlight() const;

    void SetNeighbor(int idx, Cell *val);

    std::vector<Cell *> Subdivide();

    bool Contains(const CVector3D &v);

    Cell *GetNeighbor(int idx);

    void SetPlayer(Player *player);

    Player *GetPlayer() const;

    const CVector3D &GetVert(int idx);

    std::set<Cell *> m_surroundingCells;

    int CountSurroundingCells(Player *p) const;

    static void ResetIDS() { s_id = 0; }

private:
    int m_id;
    static int s_id;

    ESTATE m_state;
    Cell *m_neighbors[5];
    Player *m_player;
    CVector3D m_verts[4];

    HighlightList m_currentHighlight;

    void InitHighlight();
};

// Used for the AI
typedef struct _CellStats
{
    std::map<Player *, int> cells_taken;
    Cell *moveFrom, *moveTo;
    Cell::ESTATE moveType;
    int total_cells_taken,
        cells_vulnerable_move,
        cells_vulnerable_nomove;
} CellStats;

#endif // __CELL_H__
